﻿using System.Security.Claims;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.JSInterop;
using SageKing.Blazor.OpenIdService.Components.Pages;
using SageKing.Core.Extensions;

using IMessageService = AntDesign.IMessageService;

namespace SageKing.Blazor.OpenIdService.Components.Base;

public class AuthLayoutComponentBase : ALayoutComponentBase
{
    public string Token { get; set; }
    public string? currentUrl;
    public string version { get; set; }
    public bool isLoadNoticeAction { get; set; } = false;

    public ErrorBoundary errorBoundary;

    [Inject]
    public ReuseTabsService ReuseTabsService { get; set; }

    [Inject]
    public AuthenticationStateProvider AuthenticationState { get; set; }

    [CascadingParameter]
    public Task<AuthenticationState> AuthStateTask { get; set; }

    [Inject]
    public new ILogger<AuthLayoutComponentBase> Logger { get; set; }


    public ClaimsPrincipal User { get; set; }
    public CustomAuthStateProvider AuthStateProvider
    {
        get
        {
            return (CustomAuthStateProvider)AuthenticationState;
        }
    }

    protected override async Task OnInitializedAsync()
    {
        try
        {
            version = 1.GetVersion().ToString();

            currentUrl = NavigationManager.Uri;

            await Task.CompletedTask;

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            Logger.LogError(ex, "MainLayout");
        }
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    { 
        if (firstRender)
        {
            // 异步等待获取锁。如果锁已被占用，此处不会阻塞线程，而是返回一个Task等待
            await _asyncLock.WaitAsync().ConfigureAwait(false);
            try
            {
                await GetAuthenticationStateAsync();

                var getToken = await AuthStateProvider.AuthService.GetToken();
                if (getToken.IsNullOrEmpty())
                {
                    await AuthStateProvider.SignOut();
                    return;
                }
                Token = getToken;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                Logger.LogError(ex, "AuthComponentBase");
            }
            finally
            {
                _asyncLock.Release();
            }
        }
    }

    public async Task GetAuthenticationStateAsync()
    {
        if (AuthenticationState == null)
        {
            NavigationManager.NavigateTo(OpenIddictUIConstants.LoginURL);
        }

        var state = await AuthStateProvider.GetAuthenticationStateAsync();

        User = state.User;

        AuthStateProvider.NavigateTo(NavigationManager.Uri, User);

        await Task.Delay(100);
    }

    public void ShowNotification(Exception ex)
    {

        Logger.LogError($"Error:ProcessError - Type: {ex.GetType()} Message: {ex.Message} StackTrace:{ex.StackTrace}");

        _ = Notice.Error(new()
        {
            Message = "错误提示",
            Description = ex.Message,
            Duration = 0,
        });

        errorBoundary.Recover();
    }

    #region collapsed
    public bool collapsed = false;
    public void toggle()
    {
        collapsed = !collapsed;
    }

    public void OnCollapse(bool isCollapsed)
    {
        Console.WriteLine($"Collapsed: {isCollapsed}");
    }

    #endregion
}
